#include "cmpdef.h"

#include "disk.h"
#include <cerrno>

#ifdef CMP_LINUX
#include <fcntl.h>
#include <unistd.h>
#endif

#ifdef CMP_WINDOWS
#include "windows.h"
#endif

namespace ntfs {

#ifdef CMP_WINDOWS

CDisk::CDisk(const tstring& fileName):
	mFileDesc(0), mFileName(fileName)
{
	mFileDesc = CreateFile(fileName.c_str(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	if (mFileDesc == INVALID_HANDLE_VALUE)
	{
		DWORD error = GetLastError();
		throw error;
	}
}

CDisk::~CDisk()
{
	if (mFileDesc)
		CloseHandle(mFileDesc);
}

void CDisk::read(void* buf, UINT32 bufSize, UINT64 offset) const
{
	LARGE_INTEGER newPos, liOffset;
	liOffset.QuadPart = offset;	
	if (!SetFilePointerEx(mFileDesc, liOffset, &newPos, FILE_BEGIN))
		throw GetLastError();
	if (!ReadFile(mFileDesc, buf, bufSize, (LPDWORD)&bufSize, NULL))
		throw GetLastError();
}

#endif  //  CMP_WINDOWS

#ifdef CMP_LINUX

CDisk::CDisk(string fileName):
    mFileDesc(0),mFileName(fileName)
{
    mFileDesc = open64(fileName.c_str(), O_RDONLY, 0);
    if (mFileDesc == -1)
        throw errno;
}

CDisk::~CDisk()
{
    close(mFileDesc);
}

void CDisk::read(void* buf, UINT32 bufSize, UINT64 offset) const
{
    int ret = pread64(mFileDesc, buf, bufSize, offset);
    if (ret == -1)
        throw errno;
}

#endif  //  CMP_LINUX

}  // namespace ntfs
